package fr.utbm.tx52.stamp.logic;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import fr.utbm.tx52.stamp.R;
import fr.utbm.tx52.stamp.logic.reception.MessageType;
import fr.utbm.tx52.stamp.logic.reception.PullService;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * Classe qui va s'occuper de toute la gestion de l'enregistrement des donn�es
 * sur le t�l�phone
 *
 * @author Xavier MICHEL (xavier.michel@utbm.fr) David LACHICHE
 * (david.lachiche@utbm.fr)
 */
public final class DataManager
{

	/**
	 * Le chemin vers les donn�es
	 */
	public static final String DATA_PATH = Constant.PICTURES_PATH_FOLDER;

	/**
	 * @see http://www.androidsnippets.com/get-my-phone-number
	 */
	public static String getMyPhoneNumber(Context c)
	{
		TelephonyManager mTelephonyMgr = (TelephonyManager) c.getSystemService(Context.TELEPHONY_SERVICE);
		return mTelephonyMgr.getLine1Number();
	}

	public static String getMy10DigitPhoneNumber(Context c)
	{
		String s = getMyPhoneNumber(c);
		return s;
	}

	/**
	 * Cr�ation du dossier des donn�es de l'application s'il n'existe pas
	 */
	public static void createApplicationDir()
	{
		File dir = new File(DataManager.DATA_PATH);
		if (!dir.exists())
		{
			dir.mkdir();
		}
	}

	/**
	 * D�fini le num�ro de t�l�phone de l'utilisateur de l'application dans les
	 * pr�f�rences
	 *
	 * D�tail : comme le probl�me est que le num�ro de t�l�phone n'est pas
	 * forc�ment le bon on laisse la possiblit� de le modifier mais cela pose un
	 * probl�me au niveau de l'identification
	 */
	public static void fixUserPhoneNumber(Context c)
	{
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
		if ("".equals(prefs.getString("phonenumber", "")))
		{
			SharedPreferences.Editor prefEditor = prefs.edit();
			prefEditor.putString("phonenumber", DataManager.getMyPhoneNumber(c));
			prefEditor.commit();
		}
	}

	/**
	 * Charge la liste des contacts associ�s � l'application
	 *
	 * @return La liste des contacts associ�s �l'application sous la forme <id,
	 * t�l�phone>
	 */
	@SuppressWarnings("unchecked")
	public static Map<Integer, String> loadAssociatedContacts(Context c)
	{

		Map<Integer, String> data = new HashMap<Integer, String>();

		try
		{
			FileInputStream fIn = c.openFileInput("contacts.dat");
			ObjectInputStream isr = new ObjectInputStream(fIn);
			data = (HashMap<Integer, String>) isr.readObject();

			Log.d(c.getClass().getName(), "loadAssociatedContacts -> ok");
		}
		catch (Exception e)
		{
			Log.d(c.getClass().getName(), "loadAssociatedContacts -> error : " + e.getMessage());
		}

		return data;
	}

	/**
	 * Ajout un contact � la liste des contacts associ�s et sauvegarde cette
	 * liste.
	 *
	 * Cela envoi �galement un sms au contact et un message au serveur pour
	 * signaler la demande d'amiti�
	 *
	 * Si le contact est d�j� dans la liste, un message est affich�
	 *
	 * @param newContact Le nouveau contact a ajouter � la liste
	 */
	public static void addAssociatedContacts(Activity a, Contact newContact)
	{

		Context c = a.getApplicationContext();

		Map<Integer, String> data = loadAssociatedContacts(c);

		if (data.keySet().contains(Integer.parseInt(newContact.getID())))
		{
			AlertDialog.Builder alertbox = new AlertDialog.Builder(a);
			alertbox.setMessage(R.string.already_added_contact);
			alertbox.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener()
			{

				public void onClick(DialogInterface dialog, int which)
				{
				}
			});
			alertbox.show();
			return;
		}

		data.put(Integer.parseInt(newContact.getID()), newContact.getPhoneNumber());

		// Envoi de l'information au serveur
		PullService.getInstance().sendMessage(MessageType.ASK_FOR_FRIEND, newContact.getPhoneNumber());

		FileOutputStream fOut = null;
		ObjectOutputStream osw = null;

		try
		{
			fOut = c.openFileOutput("contacts.dat", Context.MODE_PRIVATE);
			osw = new ObjectOutputStream(fOut);
			osw.writeObject(data);
			osw.flush();

			Log.d("DataManager", "saveAssociatedContacts -> ok");
		}
		catch (Exception e)
		{
			Log.d("DataManager", "saveAssociatedContacts -> error : " + e.getMessage());
		}
		finally
		{
			try
			{
				osw.close();
				fOut.close();
			}
			catch (IOException e)
			{
				Log.d("DataManager", "saveAssociatedContacts -> error : " + e.getMessage());
			}
		}
	}

	/**
	 * Ajout un contact � la liste des contacts associ�s et sauvegarde cette
	 * liste
	 *
	 * @param id L'identifiant du contact a rejeter de la liste
	 */
	public static void removeAssociatedContacts(Context c, Contact contact)
	{

		Map<Integer, String> data = loadAssociatedContacts(c);
		data.remove(Integer.parseInt(contact.getID()));

		// notification au server
		PullService.getInstance().sendMessage(MessageType.REMOVE_FRIEND, contact.getPhoneNumber());

		FileOutputStream fOut = null;
		ObjectOutputStream osw = null;

		try
		{
			fOut = c.openFileOutput("contacts.dat", Context.MODE_PRIVATE);
			osw = new ObjectOutputStream(fOut);
			osw.writeObject(data);
			osw.flush();

			Log.d(c.getClass().getName(), "saveAssociatedContacts -> ok");
		}
		catch (Exception e)
		{
			Log.d(c.getClass().getName(), "saveAssociatedContacts -> error : " + e.getMessage());
		}
		finally
		{
			try
			{
				osw.close();
				fOut.close();
			}
			catch (IOException e)
			{
				Log.d("DataManager", "saveAssociatedContacts -> error : " + e.getMessage());
			}
		}
	}
}
